package com.business.dynamic.service.impl;


import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.business.common.dto.R;
import com.business.common.enums.BusinessExceptionEnum;
import com.business.common.exception.BusinessException;
import com.business.dynamic.entity.Dynamic;
import com.business.dynamic.entity.DynamicLike;
import com.business.dynamic.entity.DynamicMessage;
import com.business.dynamic.entity.vo.DynamicLikeVo;
import com.business.dynamic.mapper.DynamicLikeMapper;
import com.business.dynamic.mapper.DynamicMapper;
import com.business.dynamic.service.DynamicLikeService;
import com.business.dynamic.service.DynamicMessageService;
import com.business.user.entity.UserDetailsDto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import java.util.*;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;


/**
 * 用户喜欢表:业务接口实现类
 *
 * @author chenjiehong
 * @date 2019-11-29 15:15:38
 * @since 1.0
 */
@Service
public class DynamicLikeServiceImpl implements DynamicLikeService {

    @Autowired
    private DynamicLikeMapper dynamicLikeMapper;

    @Autowired
    private DynamicMapper dynamicMapper;

    @Autowired
    private UserServiceImpl userService;

    @Autowired
    private DynamicMessageService dynamicMessageService;
    @Autowired
    private PlatformTransactionManager transactionManager;

    private ThreadPoolExecutor pool = new ThreadPoolExecutor(9, 30, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<>());

    private Logger logger = LoggerFactory.getLogger(DynamicLikeServiceImpl.class);

    @Override
    public Integer addAndCheck(DynamicLike dynamicLike) {
        Integer likeQuantity = dynamicMapper.getDynamicQuantity(dynamicLike.getDynamicId(), "like_quantity");
        if (likeQuantity == null) {
            throw new BusinessException(BusinessExceptionEnum.DYNAMIC_NOT_EXIST);
        }
        Integer count = dynamicLikeMapper.selectCount(new EntityWrapper<DynamicLike>().eq("dynamic_id", dynamicLike.getDynamicId()).eq("user_id", dynamicLike.getUserId()));
        if (count != 0) {
            throw new BusinessException(BusinessExceptionEnum.LIKE_EXIST);
        }
        //异步
        pool.execute(() -> {
            //异步情况下 @Transaction 没有效果
            DefaultTransactionDefinition def = new DefaultTransactionDefinition();
            def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); // 事物隔离级别，开启新事务，这样会比较安全些。
            TransactionStatus status = transactionManager.getTransaction(def); // 获得事务状态
            try {
                dynamicLike.setCreateTime(new Date());
                dynamicLikeMapper.insert(dynamicLike);
                Dynamic dynamic = new Dynamic();
                dynamic.setId(dynamicLike.getDynamicId());
                dynamic.setLikeQuantity(likeQuantity + 1);
                dynamicMapper.updateById(dynamic);
                Integer dynamicUserId = dynamicMapper.getDynamicUserId(dynamicLike.getDynamicId());
                //添加消息
                if(dynamicLike.getUserId() != dynamicUserId){
                    DynamicMessage dynamicMessage = new DynamicMessage();
                    dynamicMessage.setType(1);
                    dynamicMessage.setItemId(dynamicLike.getId());
                    dynamicMessage.setDynamicId(dynamicLike.getDynamicId());
                    dynamicMessage.setFromUserId(dynamicLike.getUserId());
                    //发送给动态的作者
                    dynamicMessage.setUserId(dynamicUserId);
                    dynamicMessageService.add(dynamicMessage);
                }
                //提交事务
                transactionManager.commit(status);
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
                //回滚 事务
                transactionManager.rollback(status);
            }
        });
        return likeQuantity + 1;
    }


    @Override
    public Integer delete(DynamicLike dynamicLike) {
        Integer likeQuantity = dynamicMapper.getDynamicQuantity(dynamicLike.getDynamicId(), "like_quantity");
        if (likeQuantity == null) {
            throw new BusinessException(BusinessExceptionEnum.DYNAMIC_NOT_EXIST);
        }
        dynamicLike = dynamicLikeMapper.selectOne(dynamicLike);
        if (dynamicLike == null) {
            return likeQuantity;
        }
        //异步
        DynamicLike finalDynamicLike = dynamicLike;
        pool.execute(() -> {
            //异步情况下 @Transaction 没有效果
            DefaultTransactionDefinition def = new DefaultTransactionDefinition();
            def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW); // 事物隔离级别，开启新事务，这样会比较安全些。
            TransactionStatus status = transactionManager.getTransaction(def); // 获得事务状态
            try {
                Integer result = dynamicLikeMapper.deleteById(finalDynamicLike.getId());
                if (result > 0) {
                    Dynamic dynamic = new Dynamic();
                    dynamic.setId(finalDynamicLike.getDynamicId());
                    dynamic.setLikeQuantity(likeQuantity - 1);
                    dynamicMapper.updateById(dynamic);
                    Integer dynamicUserId = dynamicMapper.getDynamicUserId(finalDynamicLike.getDynamicId());
                    if(finalDynamicLike.getUserId() != dynamicUserId){
                        //删除消息
                        dynamicMessageService.delete(finalDynamicLike.getId(), 1);
                    }
                }
                //提交事务
                transactionManager.commit(status);
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
                //回滚 事务
                transactionManager.rollback(status);
            }
        });
        return likeQuantity - 1;
    }

    @Override
    public List<DynamicLike> queryList(Integer dynamicId) {
        Wrapper<DynamicLike> wrapper = new EntityWrapper<>();
        wrapper.eq("dynamic_id", dynamicId);
        List<DynamicLike> list = dynamicLikeMapper.selectList(wrapper);
        return list;
    }

    @Override
    public  List<DynamicLikeVo> queryUserList(Integer dynamicId) {
        List<DynamicLikeVo> result = dynamicLikeMapper.queryUserList(dynamicId);
        Set<Integer> ids = new HashSet<>();
        for (DynamicLikeVo dynamicLikeVo : result) {
            ids.add(dynamicLikeVo.getUserId());
        }
        //获取用户信息
        Map<Integer, UserDetailsDto> nameMap = userService.getUserNameList(ids);
        for (DynamicLikeVo dynamicLikeVo : result) {
            UserDetailsDto userDto = nameMap.get(dynamicLikeVo.getUserId());
            if (userDto != null) {
                dynamicLikeVo.setUserRealName(userDto.getRealName());
                dynamicLikeVo.setUserHeadUrl(userDto.getHeadUrl());
            } else {
                dynamicLikeVo.setUserRealName("未设置");
            }
        }
        return result;
    }
}